import json

from django.http import HttpResponseForbidden
from django.http import JsonResponse
from django.shortcuts import render

# Create your views here.
from django.views import View
from django_redis import get_redis_connection

from carts.utils import update_redis_carts, get_cookie_data, get_cart_dict
from goods.models import SKU
from meiduo_mall.utils.response_code import RET

import pickle
import base64


class CartView(View):
    def post(self, request):

        # 获取参数，有sku_id和count
        json_data = json.loads(request.body.decode())

        sku_id = json_data.get("sku_id")

        count = json_data.get("count")

        selected = json_data.get("selected", True)

        user = request.user

        # 判断获取到的参数是否完整...
        if not all([sku_id, count]):
            return HttpResponseForbidden("参数不全...")

        # 判断count是否为整数
        try:
            count = int(count)
        except Exception as e:
            return HttpResponseForbidden("购买参数错误...")

        # 检验商品对象是否存在
        try:
            sku = SKU.objects.get(id=sku_id)
        except Exception as e:
            return HttpResponseForbidden("商品不存在")

        # 检验库存
        if int(count) > sku.stock:
            return HttpResponseForbidden("商品库存不足...")

        # 已经登陆要做的事情，数据应该加入redis数据库
        if user.is_authenticated:

            redis_conn = get_redis_connection("carts")

            # 判断需要添加的商品是否已经存在，如果已经存在就直接累加
            redis_conn.hincrby("cart_%s" % user.id, sku_id, count)

            # 存储购物车的勾选状态
            if selected:
                redis_conn.sadd("selected_%s" % user.id, sku_id)

            # 返回响应
            return JsonResponse({"code": RET.OK})

        # 没有登陆要做的事情，手动组一个cookie
        else:

            """
                {
                  sku_id1:{
                    "count":10,
                    "selected":True
                  },
                  sku_id2:{
                    "count":10,
                    "selected":True
                  }
                  ...

                }

            """
            cart_cookies = request.COOKIES.get("cart_cookies")

            cart_dict = dict()

            if cart_cookies:
                cart_dict = pickle.loads(base64.b64decode(cart_cookies.encode()))

            if sku_id in cart_dict:
                count += cart_dict[sku_id].get("count", 0)

            cart_dict[sku_id] = {"count":count, "selected": selected}

            cart_cookies = base64.b64encode(pickle.dumps(cart_dict)).decode()

            response = JsonResponse({"code": RET.OK})

            response.set_cookie("cart_cookies", cart_cookies)

            return response

            # TODO 自己写的方法
            # cart_cookies = request.COOKIES.get("cart_cookies")
            #
            # # 获取并且解码cookie字典
            # # 如果商品的cookie已经存在
            # if cart_cookies:
            #     cart_dict = pickle.loads(base64.b64decode(cart_cookies.encode()))
            #
            #     # 在字典里面获取值
            #     sub_sku_dict = cart_dict.get("sku_%s" % sku_id)
            #
            #     if sub_sku_dict:
            #         sub_sku_dict["count"] += count
            #         sub_sku_dict["selected"] = selected
            #
            #     # 如果商品的cookie不存在
            #     else:
            #
            #         sub_sku_dict = {"count": count, "selected": selected}
            #
            #         cart_dict["sku_%s" % sku_id] = sub_sku_dict
            #
            #     cart_cookies = (base64.b64encode(pickle.dumps(cart_dict))).decode()
            #
            #     response = JsonResponse({"code": RET.OK})
            #
            #     response.set_cookie("cart_cookies", cart_cookies)
            #
            #     return response
            #
            # else:
            #     cart_dict = dict()
            #
            #     sub_sku_dict = {"count": count, "selected": selected}
            #
            #     cart_dict["sku_%s" % sku_id] = sub_sku_dict
            #
            #     cart_cookies = (base64.b64encode(pickle.dumps(cart_dict))).decode()
            #
            #     response = JsonResponse({"code": RET.OK})
            #
            #     response.set_cookie("cart_cookies", cart_cookies)
            #
            #     return response

    # 展示购物车的内容
    def get(self, request):

        # 判断是否已经登陆
        user = request.user

        if user.is_authenticated:

            redis_conn = get_redis_connection("carts")

            skus = redis_conn.hgetall("cart_%s" % user.id)

            is_selected = redis_conn.smembers("selected_%s" % user.id)

            sku_lst = list()

            for sku_id, sku_amount in skus.items():

                sku = SKU.objects.get(id=sku_id)

                selected = "True" if sku_id in is_selected else "False"

                sku_dict = {"name":sku.name,
                            "price":str(sku.price),
                            "amount":str(int(sku_amount) * sku.price),
                            "selected": selected,
                            "default_image_url": sku.default_image_url.url,
                            "count": int(sku_amount),
                            "id": sku.id
                            }
                sku_lst.append(sku_dict)

            context = {"cart_skus": sku_lst}

            return render(request, "cart.html", context=context)

        # 如果用户未登陆则直接提取cookie
        else:
            cart_cookie = request.COOKIES.get("cart_cookies")

            if not cart_cookie:
                return render(request, "cart.html")

            cart_dict = pickle.loads(base64.b64decode(cart_cookie.encode()))

            # print(cart_dict)

            sku_lst = list()

            for sku_id, sku_detail in cart_dict.items():

                sku = SKU.objects.get(id=sku_id)

                sku_dict = {"name":sku.name,
                            "price":str(sku.price),
                            "amount":str(int(sku_detail["count"]) * sku.price),
                            "selected": str(sku_detail["selected"]),
                            "default_image_url": sku.default_image_url.url,
                            "count": int(sku_detail["count"]),
                            "id": sku.id
                            }
                sku_lst.append(sku_dict)

            context = {"cart_skus": sku_lst}

            return render(request, "cart.html", context=context)

    # 增加购物车商品的数量
    def put(self, request):
        # 获取数据
        user = request.user
        json_dict_data = json.loads(request.body.decode())
        sku_id = json_dict_data.get("sku_id")
        count = json_dict_data.get("count")
        selected = json_dict_data.get("selected", True)

        # 校验数据
        if not all([sku_id, count]):
            return HttpResponseForbidden("参数不全...")

        try:
            sku = SKU.objects.get(id=sku_id)

        except Exception as e:
            return HttpResponseForbidden("查无此商品...")

        if user.is_authenticated:
            # 更新redis数据库
            update_redis_carts(user, sku_id, count, selected)

            # 返回响应

            sku_dict = {"name":sku.name,
                        "price":str(sku.price),
                        "amount":str(count * sku.price),
                        "selected": selected,
                        "default_image_url": sku.default_image_url.url,
                        "count": count,
                        "id": sku.id
                        }
            context = {"code": RET.OK, "errmg": "success", "cart_sku": sku_dict}

            return JsonResponse(context)

        else:
            # 更新cookie的购物车数据
            cookie_data = request.COOKIES.get("cart_cookies")

            cart_dict = get_cart_dict(cookie_data)

            # 修改字典
            cart_dict[sku_id] = {"count":count, "selected":selected}

            sku_dict = {"name":sku.name,
                        "price":str(sku.price),
                        "amount":str(count * sku.price),
                        "selected": selected,
                        "default_image_url": sku.default_image_url.url,
                        "count": count,
                        "id": sku.id
                        }
            context = {"code": RET.OK, "errmg": "success", "cart_sku": sku_dict}

            response = JsonResponse(context)

            cookie_data = get_cookie_data(cart_dict)

            response.set_cookie("cart_cookies", cookie_data)

            return response

    # 删除购物车商品
    def delete(self, request):

        # 获取数据
        user = request.user
        json_dict_data = json.loads(request.body.decode())
        sku_id = json_dict_data.get("sku_id")

        # 校验数据的正确性
        if not sku_id:
            return HttpResponseForbidden("参数不全...")

        try:
            sku = SKU.objects.get(id=sku_id)

        except Exception as e:
            return HttpResponseForbidden("查无此商品...")

        # 判断是否登陆
        if user.is_authenticated:
            # 把数据写入redis数据库
            redis_conn = get_redis_connection("carts")

            pipeline = redis_conn.pipeline()

            pipeline.hdel("cart_%s" % user.id, sku_id)
            pipeline.srem("selected_%s" % user.id, sku_id)

            pipeline.execute()

            # 返回响应
            return JsonResponse({"code": RET.OK, "errmsg": "delete success"})

        else:
            cookie_data = request.COOKIES.get("cart_cookies")

            cart_dict = get_cart_dict(cookie_data)

            # 删除数据
            if sku_id in cart_dict:
                del cart_dict[sku_id]

            cookie_data = get_cookie_data(cart_dict)

            response = JsonResponse({"code": RET.OK, "errmsg": "delete success"})

            response.set_cookie("cart_cookies", cookie_data)

            return response


class CartSelectedAllView(View):

    def put(self, request):

        user = request.user

        json_data = request.body.decode()

        dict_data = json.loads(json_data)

        selected = dict_data.get("selected")

        if user.is_authenticated:

            redis_conn = get_redis_connection("carts")
            skus_dict = redis_conn.hgetall("cart_%s" % user.id)
            skus_id_list = skus_dict.keys()

            if selected:
                redis_conn.sadd("selected_%s" % user.id, *skus_id_list)

            else:
                redis_conn.srem("selected_%s" % user.id, *skus_id_list)

            return JsonResponse({"code":RET.OK, "errmsg":"success"})

        else:
            cookie_data = request.COOKIES.get("cart_cookies")

            if not cookie_data:
                return HttpResponseForbidden("cookie不存在...")

            cart_dict = get_cart_dict(cookie_data)

            for sku_dict in cart_dict.values():
                sku_dict["selected"] = selected

            cookie_data = get_cookie_data(cart_dict)

            response = JsonResponse({"code": RET.OK, "errmsg": "success"})

            response.set_cookie("cart_cookies", cookie_data)

            return response


class CartSimpleView(View):
    def get(self, request):

        user = request.user
        skus_list = list()

        if user.is_authenticated:

            redis_conn = get_redis_connection("carts")
            skus = redis_conn.hgetall("cart_%s" % user.id)

            for sku_id, count in skus.items():

                sku = SKU.objects.get(id=sku_id)
                sku_dict = {"id": sku.id,
                            "name": sku.name,
                            "default_image_url": sku.default_image_url.url,
                            "count": int(count)}
                skus_list.append(sku_dict)

        else:
            cookie_data = request.COOKIES.get("cart_cookies")

            if not cookie_data:
                context = {"cart_skus": skus_list}
                return JsonResponse(context)

            else:
                cart_dict = get_cart_dict(cookie_data)

                for sku_id in cart_dict:
                    sku = SKU.objects.get(id=sku_id)
                    sku_dict = {"id": sku_id,
                                "name": sku.name,
                                "default_image_url": sku.default_image_url.url,
                                "count": int(cart_dict[sku_id]["count"])}
                    skus_list.append(sku_dict)

        context = {"cart_skus": skus_list}

        return JsonResponse(context)
